#!/bin/gawk -f
#
# Extracts a record or a data item from a dbas file.
# Arguments: b  : name (can be r.e.) or number of data block [required]
#            i  : name of item [optional]
#            id : flag for printing of ident [optional]
#                 id=show: ident is printed before the data item (item extraction)
#                 id=ident: ident is printed as $ IDENT line preceding the data
#                 default: ident is not printed
#            hdr: flag for printing of header [optional]
#                 (consisting of the full $... block description (block extraction)
#                  or a line beginning with # (item extraction) )
#                 hdr=none: header is not printed
#                 default: header is printed
# Note: with block extraction the database format is maintained if: hdr!=none && id==ident
# NOTE:
#  use -v on the command line to specify the parameters when using gawk
#  see documentation on gawk (JFD@Wed Mar 15 11:36:20 CST 2000)

BEGIN {
#	if ( FILENAME == "-" ) {
# 		print "usage: dbext [b=BLOCK_NAME [i=ITEM_NAME] [hdr=none] [id=show|ident]] file"
#		print "   the BLOCK_NAME can be a regular expression, or: #BLOCK_NUMBER"
#		print "hdr: flag for printing of header [optional]"
#		print "   hdr=none: header is not printed"
#		print "   default: header is printed"
#		print "id : flag for printing of ident [optional]"
#		print "   id=show: ident is printed before the data item (item extraction)"
#		print "   id=ident: ident is printed as $ IDENT line preceding the data"
#		print "   default: ident is not printed"
#		exit( 1 )
#	}
	if ( b == "" ) {
                print b
                print "this was the value of b"
		print "The DATA records are:" > "/dev/tty"
		nrec = 0
		while ( "grep '$ DATA' " FILENAME | getline ) {
			sub( /\$ DATA */, "" )
			print ++nrec ": " $0 > "/dev/tty"
		}
		close ( "grep '$ DATA' " FILENAME )
		printf "Enter your choice (0 to end): " > "/dev/tty"
		getline < "-"
		nsel = $1
		if ( nsel == 0 )
			exit( 0 )
		if ( nsel < 0 || nsel > nrec ) {
			print "Illegal value - no data extracted" > "/dev/tty"
			exit( 1 )
		}
		b = "#"nsel
	}
	numblock = match( b, /^#/ )
	if ( numblock ) {
		block = b
		sub( /#/, "", block )
	}
	else
		block = toupper( b )
	do_item = ( i != "" )
	if ( do_item ) {
		itm = toupper( i )
		if ( hdr == "" ) print "# " block " " itm
	}
	inblock = 0
	count = 0
	blockcount = 0
	ident = "NULL_IDENT"
}

function out(   nrec, nitm, iitm, i) {
	if ( !do_item ) {
		if ( id == "show" ) print ident " "
		if ( id == "ident" ) print "$ IDENT " ident
		for ( i=1; i<= count; i++ ) {
			if ( hdr == "none" ) {
				if ( match( line[i], /^\$/ ) ) {
					split( line[i], descr )
					if ( descr[2] == "TABLE" ) i++
					continue
				}
				if ( i == count ) continue
			}
			print line[i]
		}
	}
	else {
		split( line[2], descr )
		nrec = descr[4]
		if ( descr[2] == "TEXT" ) {
			sub( /\$ TEXT */, "", line[2] )
			if ( id == "show" ) printf ident " "
			if ( id == "ident" ) print "$ IDENT " ident
			print line[2]
		}
		else if ( descr[2] == "LIST" ) {
			if ( id == "ident" ) print "$ IDENT " ident
			if ( 3+nrec == count-1 ) {
				for ( i=3; i<3+nrec; i++ ) {
					split( line[i], data )
					if ( toupper( data[1] ) == itm ) {
						sub( data[1]" *", "", line[i] )
						if ( id == "show" ) printf ident " "
						print line[i]
					}
				}
			}
			else {
				print "INCONSISTENT NUMBER OF RECORDS" > "/dev/tty"
			}
		}
		else if ( descr[2] == "TABLE" ) {
			if ( id == "ident" ) print "$ IDENT " ident
			nitm = descr[6]
			if ( 4+nrec == count-1 ) {
				split( line[3], headr )
				for ( i=1; i<= nitm; i++ ) {
					if ( toupper( headr[i] ) == itm ) iitm = i
				}
				for ( i=4; i<4+nrec; i++ ) {
					split( line[i], data )
					if ( id == "show" ) printf ident " "
					print data[iitm]
				}
			}
			else {
				print "INCONSISTENT NUMBER OF RECORDS" > "/dev/tty"
			}
		}
		else {
		    print "ILLEGAL LINE:", line[2] > "/dev/tty"
		}
	}
}

$2 == "IDENT" {
	ident = $3
	next
}

$2 == "DATA" {
	blockcount++
	if ( numblock ) {
		if ( blockcount != block ) {
			inblock = 0
			next
		}
		inblock = 1
		line[++count] = $0
		next
	}
	if ( toupper( $3 ) !~ block ) {
#	if ( toupper( $3 ) != block ) {
		inblock = 0
		next
	}
	inblock = 1
	line[++count] = $0
	next
}

$2 == "END" {
	if ( !inblock ) next
	line[++count] = $0
	line[++count] = ""
	out()
# allow for multiple occurrences of same data block
	count = 0
	inblock = 0
	next
}

!inblock { next }

{ 
    if ( do_item && $2 == "REMARK" ) next
    line[++count] = $0 
}
